<?php

/**
 * @author Martin Pernica
 * @copyright 2009
 */

class VException extends System
{
    protected $message = 'Unknown exception';
    protected $code = 0;
    protected $file;
    protected $line;
    public $show_source = true;

    /**
     * VException::__construct()
     *
     * @param mixed $message
     * @param integer $code
     * @param mixed $file
     * @param mixed $line
     * @return
     */
    function __construct($message = null, $code = 0, $file, $line)
    {
        $this->message = $message;
        $this->code = $code;
        $this->file = $file;
        $this->line = $line;

        $log = new Log('database');
        $log->write($code, 'VException', 'NOW()', $message, 'System');

        $this->__toString();
    }

    public static function _throw($message = null, $code = 0, $file, $line)
    {
        $this->message = $message;
        $this->code = $code;
        $this->file = $file;
        $this->line = $line;

        $log = new Log('database');
        $log->write($code, 'VException', 'NOW()', $message, 'System');

        $this->__toString();
    }

    final function backtrace()
    {
        echo "<table style=\"text-align: left; font-family: Verdana; font-weight: normal; font-size: 14px; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;\">\n";
        $sOut = "";
        $aCallstack = debug_backtrace();

        echo "<thead><tr><th></th><th>File</th><th>Line</th><th>Function</th>" .
            "</tr></thead>\n";
        $i = 1;
        foreach ($aCallstack as $aCall) {
            if (!isset($aCall['file']))
                $aCall['file'] = '[PHP Kernel]';
            if (!isset($aCall['line']))
                $aCall['line'] = '';

            echo "<tr><td><strong>#" . $i . "</strong></td><td>{$aCall["file"]}</td><td>{$aCall["line"]}</td>" .
                "<td>{$aCall["function"]}</td></tr>\n";
            $i++;
        }
        echo "</table>\n";
    }

    /**
     * VException::getMessage()
     *
     * @return
     */
    final function getMessage()
    {
        echo $this->message;
    }
    /**
     * VException::getCode()
     *
     * @return
     */
    final function getCode()
    {
        echo $this->code;
    }
    /**
     * VException::getFile()
     *
     * @return
     */
    final function getFile()
    {
        echo $this->file;
    }
    /**
     * VException::getLine()
     *
     * @return
     */
    final function getLine()
    {
        echo $this->line;
    }


    /**
     * VException::__toString()
     *
     * @return String of error
     */
    function __toString()
    {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' .
            "\n";
        echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n";
        echo '<head>' . "\n";
        echo '<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />' . "\n";
        echo '<title>Exception</title>' . "\n";
        echo "
<script type=\"text/javascript\" src=\"" . System::$url .
            "plugins/content/mootools.js\"></script>\n
<script type=\"text/javascript\" src=\"" . System::$url .
            "plugins/content/mootools-more.js\"></script>\n
		";
        echo "
<script type=\"text/javascript\">\n
            window.addEvent('domready', function(){\n
    var accordion = new Accordion($$('.toggler'),$$('.element'), {\n
        opacity: 0,\n
        onActive: function(toggler) { toggler.setStyle('color', '#4197E3'); },\n
        onBackground: function(toggler) { toggler.setStyle('color', '#4197E3'); }\n
    });\n
});\n
        </script>\n
		";
        echo '
        <style type="text/css">
	/* <![CDATA[ */
		body {
			font-family: Verdana, sans-serif;
			font-size: 78%;
			background: white;
			color: #333;
			line-height: 1.5;
			margin: 0 0 2em;
			padding: 0;
			color: white;
		}

		h1 {
			font-weight: bold !important;
			font-size: 18pt;
			margin: .6em 0;
			font-family:Verdana;
			color:white;

		}

		h2 {
			font-family: sans-serif;
			font-weight: normal;
			font-size: 14pt;
			color: #4197E3;
			margin: .6em 0;
		}
		/*
		.toggler {
			background-image: url(\'' . $GLOBALS['url'] .
            'libs/icons/bullet_toggle_plus.png\');
			background-position: right center;
			background-repeat: no-repeat;
			padding-right: 20px;
		}
		*/
		.header {
			border-bottom: 1px solid #eee;
			padding: 1px 2em;
			background: red;
		}

		.code {
            background: #f5f5f5;
			white-space:pre-wrap;
			display:block;
			margin:5px;
			padding:5px;
			color:black;
		}

		.backtrace tr {
			padding-top: 5px;
		}

		.content {
			padding-left: 30px;
		}

		.footer {
			margin-top: 20px;
			paddint-top 10px;
			width: 100%;
			border-top: thin #ebebeb solid;
			color: black;
		}
	/* ]]> */
	</style>
		';
        echo '</head><body>' . "\n";

        echo '<div class="header">
		<h1>Uncaught exception</h1>';
        echo '<p>' . $this->message . '</p>
		</div>' . "\n";

        echo '<div class="content"><h2>Description</h2>' . "\n";
        echo '<p style="color:black"><strong>Code ' . $this->code . '</strong> : <em>' .
            $this->message . '</em> on line <strong>' . $this->line .
            ' in file</strong> <strong>' . $this->file . '</strong></p>' . "\n";

        if ($this->show_source === true) {

            echo '<h2 class="toggler">File</h2><div class="element">' . "\n";
            echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
                "\n";
            $handle = fopen($this->file, "r");
            $file = fread($handle, filesize($this->file));
            fclose($handle);
            $file = "\n" . $file;
            $file = explode("\n", $file);

            if ($this->line < 1 and $this->line > 10) {
                $start_line = $this->line - 1;
            } else {
                $start_line = $this->line - 7;
            }

            $end_line = $this->line + 7;
            echo '<table style="text-align: left; font-family: Verdana; font-size: small; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;">';
            for ($i = $start_line; $i <= $end_line; $i++) {
                echo ($this->line == $i) ? '<tr style="background-color:red; color:white;">' :
                    '<tr>';
                echo '<td>Line ' . $i . '</td><td>' . htmlspecialchars($file[$i]) . '</td></tr>';
            }
            echo '</table>';
            echo "\n</div></div>\n";

        }

        echo '<h2 class="toggler">Stack Trace</h2><div class="element">' . "\n";
        echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
            "\n";
        self::backtrace();
        echo "\n</div></div>\n";

        echo '<h2 class="toggler">$_SERVER</h2><div class="element">' . "\n";
        echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
            "\n";
        echo '<table style="text-align: left; font-family: Verdana; font-weight: normal; font-size: 14px; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;">';
        echo "<thead><tr><th>Key</th><th>Value</th>" . "</tr></thead>\n";
        foreach ($_SERVER as $key => $value) {
            echo '<tr><td><strong>' . $key . '</strong></td><td>' . $value . '</td></tr>' .
                "\n";
        }
        echo '</table></div></div>' . "\n";

        echo '<h2 class="toggler">$_GET</h2><div class="element">' . "\n";
        echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
            "\n";
        echo '<table style="text-align: left; font-family: Verdana; font-weight: normal; font-size: 14px; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;">';
        echo "<thead><tr><th>Key</th><th>Value</th>" . "</tr></thead>\n";
        foreach ($_GET as $key => $value) {
            echo '<tr><td><strong>' . $key . '</strong></td><td>' . $value . '</td></tr>' .
                "\n";
        }
        echo '</table></div></div>' . "\n";

        echo '<h2 class="toggler">$_POST</h2><div class="element">' . "\n";
        echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
            "\n";
        echo '<table style="text-align: left; font-family: Verdana; font-weight: normal; font-size: 14px; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;">';
        echo "<thead><tr><th>Key</th><th>Value</th>" . "</tr></thead>\n";
        foreach ($_POST as $key => $value) {
            echo '<tr><td><strong>' . $key . '</strong></td><td>' . $value . '</td></tr>' .
                "\n";
        }
        echo '</table></div></div>' . "\n";

        echo '<h2 class="toggler">$_COOKIE</h2><div class="element">' . "\n";
        echo '<div style="font-family:Consolas, monospace;font-weight:x-small;background-color:#ebebeb;line-break: strict;width:850px;padding: 5px 5px 5px 5px;">' .
            "\n";
        echo '<table style="text-align: left; font-family: Verdana; font-weight: normal; font-size: 14px; color: #404040; width: 100%; background-color: #fafafa; border-collapse: collapse; border-spacing: 0px;">';
        echo "<thead><tr><th>Key</th><th>Value</th>" . "</tr></thead>\n";
        foreach ($_COOKIE as $key => $value) {
            echo '<tr><td><strong>' . $key . '</strong></td><td>' . $value . '</td></tr>' .
                "\n";
        }
        echo '</table></div></div>' . "\n";


        echo "</div>\n";

        echo '<div class="footer">';
        $referer = (!empty($_SERVER["HTTP_REFERER"])) ? $_SERVER["HTTP_REFERER"] :
            '<em>Empty</em>';
        echo '<ul>
		<li>Powered by VisionCMS ' . VERSION . '</li>
        <li>PHP version ' . phpversion() . '</li>
        <li>Zend version ' . zend_version() . '</li>
        <li>Referrer ' . $referer . '</li>
        <li>Report generated at <strong>' . date("m/d/y H:i:s") .
            '</strong></li>
        </ul>
        </div>
		';

        echo '</body></html>';
        exit;
    }

}

?>